home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / pascal / tvtool2.zip / DEMO.PAS < prev    next >
Pascal/Delphi Source File  |  1993-07-20  |  52KB  |  1,859 lines

  1. {*
  2. *   TV Tool Box Version 2.0
  3. *   Copyright 1992,93 by Richard W. Hansen, All Rights Reserved.
  4. *
  5. *
  6. *   Demo.pas
  7. *   A demo of TV TOOL BOX for Turbo Pascal 7.0.
  8. *
  9. *}
  10.  
  11. Program TV_TOOL_BOX_DEMO;
  12. {$F-}
  13. {$X+}
  14. {$B+}
  15. {$V-}
  16. {$S+}
  17. {$R+}
  18. {$N+}
  19.  
  20. {$I TVDEFS.INC}
  21.  
  22.  
  23. USES
  24.   Crt, Dos,
  25.   Objects, Drivers, Views, Menus, Dialogs, App, MsgBox, StdDlg, Validate,
  26.   TvApp, TvConst, TvViews, TvDialog, TvMenus, TvInput, Tv3D,
  27.   TvObject, TvString, TvType;
  28.  
  29.  
  30. CONST
  31.   MaxLines          = 500;        { max file buffer lines }
  32.   MaxBuf            = 32768;      { max file buffer size  }
  33.  
  34.   cmFileOpen        = 100;
  35.   cmNewText         = 101;
  36.   cmNewWin          = 102;
  37.   cmNewFormatText   = 103;
  38.   cmNewAsciiHex     = 104;
  39.   cmMsgDialog       = 105;
  40.   cmNewEditLine     = 106;
  41.   cmAbout           = 107;
  42.   cmSetup           = 108;
  43.   cmTestPct         = 109;
  44.   cmTestPrt         = 110;
  45.   cmTestWrite       = 111;
  46.   cmTest3D          = 112;
  47.   cmNone            = 113;
  48.   cmTestBox1        = 114;
  49.   cmTestBox2        = 115;
  50.   cmTestBox3        = 116;
  51.   cmTestPictures    = 117;
  52.   cmSearch          = 999;
  53.   cmTool1           = 1000;
  54.   cmTool2           = cmTool1 + 1;
  55.   cmTool3           = cmtool2 + 1;
  56.   cmTool4           = cmTool3 + 1;
  57.   cmTool5           = cmTool4 + 1;
  58.   cmTool6           = cmTool5 + 1;
  59.   cmTool7           = cmTool6 + 1;
  60.   cmItem1           = cmMarkStart;
  61.   cmItem2           = cmItem1 + 1;
  62.   cmItem3           = cmItem2 + 1;
  63.   cmItem4           = cmItem3 + 1;
  64.  
  65.   WinCount          : Integer =   0;
  66.   MaxLong           = 99999;
  67.  
  68.  
  69. TYPE
  70.   { data entry test dialog data record }
  71.   DataRec = record
  72.     S1 : String[10];
  73.     S2 : String[21];
  74.     S3 : String[21];
  75.     S4 : String[21];
  76.     I1 : Word;
  77.     I2 : Integer;
  78.     H1 : LongInt;
  79.     S5 : String[8];
  80.     S6 : String[8];
  81.     S7 : String[10];
  82.     S8 : String[10];
  83.     R1 : Real;
  84.     {$IFOPT N+}
  85.     D1 : Double;
  86.     {$ENDIF}
  87.     S9 : String[12];
  88.     Dt1: TbxDateRec;
  89.     Dt2: TbxDateRec;
  90.     SX1: Integer;
  91.     SX2: Integer;
  92.     SX3: Integer;
  93.     X  : Word;
  94.   end;
  95.  
  96.  
  97. TYPE
  98.   { data object for the virtual list box }
  99.   PLong = ^TLong;
  100.   TLong = Object(TObject)
  101.     Val : LongInt;
  102.   end;
  103.  
  104.  
  105.   { virtual list box }
  106.   PVirtList  = ^TVirtList;
  107.   TVirtList  = Object(TbxVListBox)
  108.     Current : LongInt;
  109.  
  110.     Function    GetText(Item: Integer;
  111.                         MaxLen: Integer): String;         Virtual;
  112.     Function    GetItem(ACommand : Word): PObject;        Virtual;
  113.     Function    MatchItem(P : PObject): Boolean;          Virtual;
  114.   end;
  115.  
  116.  
  117.   { dialog for virtual list box }
  118.   PVirtDialog = ^TVirtDialog;
  119.   TVirtDialog = Object(TDialog)
  120.     VList : PCollection;
  121.     VBox  : PVirtList;
  122.     Long  : PbxLongEdit;
  123.  
  124.     Constructor Init;
  125.     Destructor  Done;                                     Virtual;
  126.     Procedure   HandleEvent(var Event : TEvent);          Virtual;
  127.   end;
  128.  
  129.  
  130.   PMyValidator  = ^TMyValidator;
  131.   TMyValidator  = Object(TValidator)
  132.     Function IsValid(const S : String): Boolean;           Virtual;
  133.   end;
  134.  
  135.  
  136.   PCityColl = ^TCityColl;
  137.   TCityColl = object(TStringCollection)
  138.     Constructor Init;
  139.   end;
  140.  
  141.  
  142.   { interior for standard file viewer }
  143.   PFileView = ^TFileView;
  144.   TFileView = object(TScroller)
  145.     Constructor Init(var Bounds: TRect;
  146.                          AHScrollBar,
  147.                          AVScrollBar: PScrollBar);
  148.     Procedure   Draw;                                     Virtual;
  149.   end;
  150.  
  151.  
  152.   { standard file viewer window }
  153.   PFileWindow = ^TFileWindow;
  154.   TFileWindow = Object(TbxWindow)
  155.     Interior: PFileView;
  156.  
  157.     Constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
  158.     Function    MakeInterior(Bounds: TRect): PFileView;
  159.   end;
  160.  
  161.  
  162.   PPctDialog  = ^TPctDialog;
  163.   TPctDialog  = Object(TbxPercentDialog)
  164.     Procedure   Process;                                Virtual;
  165.   end;
  166.  
  167.  
  168.   PPrtDialog  = ^TPrtDialog;
  169.   TPrtDialog  = Object(TbxPrintDialog)
  170.     X : Word;
  171.  
  172.     Procedure   Process;                                Virtual;
  173.   end;
  174.  
  175.  
  176.   PHeapView = ^THeapView;
  177.   THeapView = object(TView)
  178.     OldMem : LongInt;
  179.  
  180.     Constructor Init(var Bounds: TRect);
  181.     Procedure   Draw;                                   Virtual;
  182.     Procedure   Update;
  183.   end;
  184.  
  185.  
  186.   TMyApp = object(TbxApplication)
  187.     HeapView  : PHeapView;      { a memory indicator }
  188.     DlgData   : DataRec;
  189.  
  190.     Constructor Init;
  191.     Procedure   About;
  192.     Procedure   HandleEvent(var Event: TEvent);         Virtual;
  193.     Procedure   InitMenuBar;                            Virtual;
  194.     Procedure   InitStatusLine;                         Virtual;
  195.     Procedure   InitDeskTop;                            Virtual;
  196.     Procedure   Idle;                                   Virtual;
  197.     Procedure   PercentTest;
  198.     Procedure   PrintTest;
  199.     Procedure   Setup;
  200.     Procedure   Test3D;
  201.     Procedure   TestSelectBox1;
  202.     Procedure   TestSelectBox2;
  203.     Procedure   MessageDialog;
  204.     Procedure   NewWindow;
  205.     Procedure   OpenFile;
  206.     Procedure   ReadFile(FileToRead : PathStr);
  207.     Procedure   WritelnText;
  208.     Procedure   NewText;
  209.     Procedure   NewFormatText;
  210.     Procedure   NewAsciiHex;
  211.     Procedure   NewDataEntry;
  212.     Procedure   TestPictures;
  213.     Procedure   TestVList;
  214.   end;
  215.  
  216. VAR
  217.   { global file buffer data, used by multiple windows }
  218.   LineCount : Integer;
  219.   Lines     : Array[0..MaxLines - 1] of PString;
  220.   Buf       : PbxCharArray;
  221.   BufSize   : Word;
  222.   BufName   : PathStr;
  223.  
  224.  
  225. { TVirtDialog }
  226.  
  227. Constructor TVirtDialog.Init;
  228.  
  229.   var
  230.     R   : TRect;
  231.     Bar : PScrollBar;
  232.     P   : PLong;
  233.     i   : Integer;
  234.  
  235.   Begin
  236.     { CONSTRUCT A VIRTUAL LIST BOX }
  237.     R.Assign(14,1,66,16);
  238.     Inherited Init(R, 'Virtual List Box');
  239.     Options := $1143;
  240.  
  241.     R.Assign(24,3,25,13);
  242.     Bar := New(PScrollbar, Init(R));
  243.     Insert(Bar);
  244.  
  245.     R.Assign(4,3,24,13);
  246.     VBox := New(PVirtList, Init(R, 1, nil, Bar));
  247.     Insert(VBox);
  248.  
  249.     { build initial list }
  250.     { for demo purposes just create a list of many integers }
  251.     New(VList, Init(100, 0));
  252.  
  253.     for i := 1 to VList^.Limit do
  254.     begin
  255.       New(P, Init);
  256.       P^.Val := i;
  257.       VList^.Insert(P);
  258.     end;
  259.  
  260.     { set some the flags and add list to list box }
  261.     VBox^.AtMin := True;
  262.     VBox^.AtMax := False;
  263.     VBox^.NewList(VList);
  264.  
  265.  
  266.     R.Assign(4,2,13,3);
  267.     Insert(New(PLabel, Init(R, 'List Box', VBox)));
  268.  
  269.     { add buttons for paging up and down }
  270.     R.Assign(27,3,38,5);
  271.     Insert(New(PButton, Init(R, '~<~< More', cmPrevPage, bfBroadcast+bfNormal)));
  272.  
  273.     R.Assign(38,3,49,5);
  274.     Insert(New(PButton, Init(R, 'More ~>~>', cmNextPage, bfBroadcast+bfNormal)));
  275.  
  276.     { add jump to first and last item buttons }
  277.     R.Assign(27,5,38,7);
  278.     Insert(New(PButton, Init(R, '~F~irst', cmFirstPage, bfBroadcast+bfNormal)));
  279.  
  280.     R.Assign(38,5,49,7);
  281.     Insert(New(PButton, Init(R, '~L~ast', cmLastPage, bfBroadcast+bfNormal)));
  282.  
  283.     { add an input line for entering a search value }
  284.     R.Assign(34,8,42,9);
  285.     Long := New(PbxLongEdit, Init(R, '#####', 0, 0));
  286.     Insert(Long);
  287.  
  288.     { add a search button }
  289.     R.Assign(32,10,44,12);
  290.     Insert(New(PButton, Init(R, '~S~earch', cmSearch, bfNormal)));
  291.  
  292.     R.Assign(32,12,44,14);
  293.     Insert(New(PButton, Init(R, '~C~ancel', cmCancel, bfNormal)));
  294.  
  295.     SelectNext(False);
  296.   end;
  297.  
  298. Destructor TVirtDialog.Done;
  299.   begin
  300.     Inherited Done;
  301.     Dispose(VList, Done);
  302.   end;
  303.  
  304. Procedure TVirtDialog.HandleEvent(var Event : TEvent);
  305.  
  306.   var
  307.     P : PLong;
  308.  
  309.   begin
  310.     Inherited HandleEvent(Event);
  311.  
  312.     { handle the search button }
  313.     if (Event.What = evCommand) and (Event.Command = cmSearch) then
  314.     begin
  315.       { create an object identical to the list box collection and
  316.         equal to the search value from the input line
  317.       }
  318.       New(P, Init);
  319.       Long^.GetData(P^.Val);
  320.  
  321.       { call the LookUp method, if found the list box is redrawn
  322.         automatically
  323.       }
  324.       if not VBox^.Lookup(P) then
  325.       begin
  326.         Dispose(P, Done);
  327.         MessageBox('Value not found', nil, mfInformation or mfOkButton);
  328.       end;
  329.     end;
  330.   end;
  331.  
  332.  
  333. { TVirtList }
  334.  
  335. Function TVirtList.GetText(Item: Integer; MaxLen: Integer): String;
  336.  
  337.   var
  338.     S : String[20];
  339.  
  340.   begin
  341.     if (List <> nil) then
  342.       Str(PLong(List^.At(Item))^.Val:MaxLen - 3, S)
  343.     else
  344.       S := '';
  345.  
  346.     GetText := S;
  347.   end;
  348.  
  349. Function TVirtList.GetItem(ACommand : Word): PObject;
  350.  
  351.   var
  352.     P : PLong;
  353.  
  354.   begin
  355.     { This method is customized for each list box. It establishes
  356.       position in the "file" retrieves the next item as specified by the
  357.       ACommand parameter. This function returns a pointer to an object
  358.       that can be inserted into the list box.
  359.  
  360.       Since the list is integers, the integer value  Current serves as
  361.       a current position and value.
  362.     }
  363.     Case ACommand of
  364.       vlListMin : { first item in the list }
  365.       begin
  366.         { set positioning }
  367.         Current := PLong(List^.At(0))^.Val;
  368.         { create a new item }
  369.         New(P, Init);
  370.         { set the item data }
  371.         P^.Val := Current;
  372.       end;
  373.  
  374.       vlListMax : { last item in the list }
  375.       begin
  376.         Current := PLong(List^.At(List^.Count - 1))^.Val;
  377.         New(P, Init);
  378.         P^.Val := Current;
  379.       end;
  380.  
  381.       vlMin : { first item in the "file" }
  382.       begin
  383.         Current := 1;
  384.         New(P, Init);
  385.         P^.Val := Current;
  386.       end;
  387.  
  388.       vlMax : { last item in the "file" }
  389.       begin
  390.         Current := MaxLong;
  391.         New(P, Init);
  392.         P^.Val := Current;
  393.       end;
  394.  
  395.       vlNext : { next item, based on the last position }
  396.       begin
  397.         if (Current < MaxLong) then
  398.         begin
  399.           Inc(Current);
  400.           New(P, Init);
  401.           P^.Val := Current;
  402.         end
  403.  
  404.         else
  405.           P := nil
  406.       end;
  407.  
  408.       vlPrev : { previous item, based on last position }
  409.       begin
  410.         if (Current > 1) then
  411.         begin
  412.           Dec(Current);
  413.           New(P, Init);
  414.           P^.Val := Current;
  415.         end
  416.  
  417.         else
  418.           P := nil
  419.       end;
  420.  
  421.       vlCurrent : { item at the current position }
  422.       begin
  423.         New(P, Init);
  424.         P^.Val := Current;
  425.       end;
  426.     end;
  427.  
  428.     GetItem := P;
  429.   end;
  430.  
  431. Function TVirtList.MatchItem(P : PObject): Boolean;
  432.   begin
  433.     { This method attemps to match the item pointed by P to an item
  434.       in the "file". P points to the same object type ast in the
  435.       list box collection.
  436.     }
  437.     if (P <> nil) and (PLong(P)^.Val > 0) and (PLong(P)^.Val <= MaxLong) then
  438.     begin
  439.       Current := PLong(P)^.Val;
  440.       MatchItem := True;
  441.     end
  442.  
  443.     else
  444.       MatchItem := False;
  445.   end;
  446.  
  447.  
  448. { TMyValidator }
  449.  
  450. Function TMyValidator.IsValid(const S: string): Boolean;
  451.   begin
  452.     { This is a dummy function to demo how TV validators can be
  453.       used to do post edit processing of a field.
  454.     }
  455.     MessageBox('TValiditors can be used for' + ^M +
  456.                'post-edit control!', nil, mfInformation + mfOKButton);
  457.     IsValid := True;
  458.   end;
  459.  
  460.  
  461. { THeapView }
  462.  
  463. Constructor THeapView.Init(var Bounds: TRect);
  464.   begin
  465.     TView.Init(Bounds);
  466.     OldMem := 0;
  467.   end;
  468.  
  469. Procedure THeapView.Draw;
  470.   var
  471.     S: String;
  472.     B: TDrawBuffer;
  473.     C: Byte;
  474.  
  475.   begin
  476.     OldMem := MemAvail;
  477.     Str(OldMem:Size.X-1, S);
  478.     C := GetColor(2);
  479.     MoveChar(B, ' ', C, Size.X);
  480.     MoveStr(B, S, C);
  481.     WriteLine(0, 0, Size.X, 1, B);
  482.   end;
  483.  
  484. Procedure THeapView.Update;
  485.   begin
  486.     if (OldMem <> MemAvail) then DrawView;
  487.   end;
  488.  
  489.  
  490. { TCityColl }
  491.  
  492. Constructor TCityColl.Init;
  493.   begin
  494.     { create a collection of a few city names }
  495.     Inherited Init(15, 10);
  496.     Insert(NewStr('Scotts Valley'));
  497.     Insert(NewStr('Sydney'));
  498.     Insert(NewStr('Copenhagen'));
  499.     Insert(NewStr('London'));
  500.     Insert(NewStr('Paris'));
  501.     Insert(NewStr('Munich'));
  502.     Insert(NewStr('Milan'));
  503.     Insert(NewStr('Tokyo'));
  504.     Insert(NewStr('Stockholm'));
  505.     Insert(NewStr('New York'));
  506.     Insert(NewStr('Redmond'));
  507.     Insert(NewStr('Zurich'));
  508.     Insert(NewStr('Athens'));
  509.     Insert(NewStr('Brussels'));
  510.     Insert(NewStr('Chicago'));
  511.   end;
  512.  
  513.  
  514. { TFileView }
  515.  
  516. Constructor TFileView.Init(var Bounds: TRect;
  517.                                AHScrollBar, AVScrollBar: PScrollBar);
  518.   begin
  519.     TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
  520.     Options := Options or ofFramed;
  521.     SetLimit(128, LineCount);
  522.   end;
  523.  
  524. Procedure TFileView.Draw;
  525.  
  526.   var
  527.     Color: Byte;
  528.     I, Y: Integer;
  529.     B: TDrawBuffer;
  530.  
  531.   begin
  532.     Color := GetColor(1);
  533.  
  534.     for Y := 0 to Size.Y - 1 do
  535.     begin
  536.       MoveChar(B, ' ', Color, Size.X);
  537.       i := Delta.Y + Y;
  538.  
  539.       if (I < LineCount) and (Lines[I] <> nil) then
  540.         MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color);
  541.  
  542.       WriteLine(0, Y, Size.X, 1, B);
  543.     end;
  544.   end;
  545.  
  546.  
  547. { TFileWindow }
  548.  
  549. Constructor TFileWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word);
  550.   begin
  551.     TbxWindow.Init(Bounds, WinTitle, WindowNo);
  552.     GetExtent(Bounds);
  553.     Interior := MakeInterior(Bounds);
  554.     Insert(Interior);
  555.     Options := Options OR ofTileable;
  556.   end;
  557.  
  558. Function TFileWindow.MakeInterior(Bounds: TRect): PFileView;
  559.  
  560.   var
  561.     HScrollBar,
  562.     VScrollBar: PScrollBar;
  563.     R : TRect;
  564.     P : PFileView;
  565.  
  566.   begin
  567.     R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1);
  568.     VScrollBar := New(PScrollBar, Init(R));
  569.     VScrollBar^.Options := VScrollBar^.Options or ofPostProcess;
  570.     Insert(VScrollBar);
  571.  
  572.     R.Assign(Bounds.A.X+1, Bounds.B.Y-1, Bounds.B.X-1, Bounds.B.Y);
  573.     HScrollBar := New(PScrollBar, Init(R));
  574.     HScrollBar^.Options := HScrollBar^.Options or ofPostProcess;
  575.     Insert(HScrollBar);
  576.  
  577.     Bounds.Grow(-1,-1);
  578.     P := New(PFileView, Init(Bounds, HScrollBar, VScrollBar));
  579.     P^.GrowMode := gfGrowHiX + gfGrowHiY;
  580.     MakeInterior := P;
  581.   end;
  582.  
  583.  
  584. { TPctDialog }
  585.  
  586. Procedure TPctDialog.Process;
  587.   begin
  588.     { here is where the works gets done, in this case we just
  589.       delay a bit then bump the counter
  590.     }
  591.     if (RunState > 0) and (RunState < cmCancelJob) then
  592.     begin
  593.       if (RunState <> cmPauseJob) then
  594.       begin
  595.         Delay(5);
  596.         Increment;
  597.  
  598.         if (Count = 500) then
  599.           ChangeMessage('Half way there')
  600.         else if (Count >= Total) then
  601.         begin
  602.           RunState := cmJobComplete;
  603.           Delay(1000);
  604.         end;
  605.       end;
  606.     end;
  607.   end;
  608.  
  609.  
  610. { TPrtDialog }
  611.  
  612. Procedure TPrtDialog.Process;
  613.  
  614.   var
  615.     N : String[5];
  616.  
  617.   begin
  618.     { Here is where the works gets done. In this case we pretend to print
  619.       a line then exit.
  620.     }
  621.     Case RunState of
  622.       cmStartJob : {DO SETUP AND START PRINTING}
  623.         begin
  624.           RunState := cmContinueJob;
  625.         end;
  626.  
  627.       cmContinueJob : {PRINT NEXT LINE}
  628.         begin
  629.           Inc(X);
  630.           Delay(100); {print line here}
  631.           Str(X,N);
  632.           ChangeMessage('Printing Line ' + N);
  633.  
  634.           if (X = 250) then
  635.             RunState := cmJobComplete;
  636.         end;
  637.  
  638.       cmPauseJob : {DO NOTHING}
  639.         ;
  640.  
  641.       cmCancelJob : {SHUT DOWN}
  642.         ;
  643.     end;
  644.   end;
  645.  
  646.  
  647. { TMyApp }
  648.  
  649. Constructor TMyApp.Init;
  650.  
  651.   var
  652.     Event : TEVent;
  653.     R     : TRect;
  654.  
  655.   begin
  656.     Inherited Init;
  657.     ReadFile('READ.ME');
  658.     { make a heap viewer }
  659.     GetExtent(R);
  660.     R.A.X := R.B.X - 7;
  661.     R.B.X := R.B.X - 1;
  662.     R.B.Y := R.A.Y + 1;
  663.     HeapView := New(PHeapView, Init(R));
  664.     Insert(HeapView);
  665.     FillChar(DlgData, SizeOf(DlgData), 0);
  666.     NewFormatText;
  667.     Event.What := evCommand;
  668.     Event.Command := cmAbout;
  669.     PutEvent(Event);
  670.   end;
  671.  
  672. Procedure TMyApp.InitDesktop;
  673.  
  674.   var
  675.     P : Pbx3DToolBar;
  676.     R : TRect;
  677.  
  678.   begin
  679.     Inherited InitDesktop;
  680.     { setup a 3D tool bar }
  681.     { TOOL BARS SHOULD ALWAYS BE THE FIRST THING INSERTED INTO THE
  682.       DESKTOP!
  683.     }
  684.     R.Assign(0,0, 8,4);
  685.     P := New(Pbx3DToolBar, Init(R, True));
  686.     P^.AddTool('  Save  '^M+'File', CmTool1);
  687.     P^.AddTool('  Open  '^M+'File', CmTool2);
  688.     P^.AddTool('  New   '^M+'File', CmTool3);
  689.     P^.AddTool('  Edit  ', CmTool4);
  690.     P^.AddTool('  Cut   ', CmTool5);
  691.     P^.AddTool(' Paste  ', CmTool6);
  692.     Desktop^.Insert(P);
  693.   end;
  694.  
  695. Procedure TMyApp.HandleEvent(var Event: TEvent);
  696.  
  697.   var
  698.     R : TRect;
  699.  
  700.   begin
  701.     Inherited HandleEvent(Event);
  702.  
  703.     if Event.What = evCommand then
  704.     begin
  705.       case Event.Command of
  706.         cmNewEditLine   : NewDataEntry;
  707.         cmNewAsciiHex   : NewAsciiHex;
  708.         cmNewFormatText : NewFormatText;
  709.         cmNewText       : NewText;
  710.         cmTestWrite     : WritelnText;
  711.         cmFileOpen      : OpenFile;
  712.         cmNewWin        : NewWindow;
  713.         cmMsgDialog     : MessageDialog;
  714.         cmAbout         : About;
  715.         cmTestPct       : PercentTest;
  716.         cmTestPrt       : PrintTest;
  717.         cmSetup         : Setup;
  718.         cmTest3D        : Test3D;
  719.         cmTestBox1      : TestSelectBox1;
  720.         cmTestBox2      : TestSelectBox2;
  721.         cmTestBox3      : TestVList;
  722.         cmTestPictures  : TestPictures;
  723.         cmTool1         : MessageBox('SAVE TOOL', nil, mfInformation+ mfOkButton);
  724.         cmTool2         : MessageBox('OPEN TOOL', nil, mfInformation+ mfOkButton);
  725.         cmTool3         : MessageBox('NEW TOOL', nil, mfInformation+ mfOkButton);
  726.         cmTool4         : MessageBox('EDIT TOOL', nil, mfInformation+ mfOkButton);
  727.         cmTool5         : MessageBox('CUT TOOL', nil, mfInformation+ mfOkButton);
  728.         cmTool6         : MessageBox('PASTE TOOL', nil, mfInformation+ mfOkButton);
  729.         cmTile          :
  730.           begin
  731.             Desktop^.GetExtent(R);
  732.             Desktop^.Tile(R);
  733.           end;
  734.         cmCascade       :
  735.           begin
  736.             Desktop^.GetExtent(R);
  737.             Desktop^.Cascade(R);
  738.           end;
  739.         cmItem1..cmItem4: { Check mark menu items }
  740.           { set the selected menu item to checked }
  741.           PbxMenuBar(MenuBar)^.ResetMarkers(cmItem1, cmItem4, Event.Command);
  742.       else
  743.         Exit;
  744.       end;
  745.  
  746.       ClearEvent(Event);
  747.     end;
  748.   end;
  749.  
  750. Procedure TMyApp.Idle;
  751.   begin
  752.     Inherited Idle;
  753.     HeapView^.Update;
  754.   end;
  755.  
  756. Procedure TMyApp.InitMenuBar;
  757.  
  758.   var
  759.     R : TRect;
  760.     S : String[3];
  761.  
  762.   begin
  763.     S := ' ';
  764.  
  765.     (* UNCOMMENT THIS TO TRY CHECK MARK MENUS WITH A DIFFERENT MARKER.
  766.  
  767.     TvMenus.Marker    := 'ON ';
  768.     Tvmenus.NoMarker  := 'OFF';
  769.     TvMenus.MarkerLen := 3;
  770.     S := '   ';
  771.     *)
  772.  
  773.     GetExtent(R);
  774.     R.B.Y := R.A.Y + 1;
  775.     MenuBar := New(PbxMenuBar, Init(R,
  776.     NewMenu(
  777.       NewSubMenu('~≡~', hcNoContext,
  778.       NewMenu(
  779.         NewItem('~A~bout...',               '',     kbNoKey,  cmAbout,          hcNoContext,
  780.         nil)),
  781.       NewSubMenu('~F~ile', hcNoContext,
  782.       NewMenu(
  783.         NewItem('~O~pen...',                'F3',   kbF3,     cmFileOpen,       hcNoContext,
  784.         NewLine(
  785.         NewItem('E~x~it',                   'Alt-X',kbAltX,   cmQuit,           hcNoContext,
  786.         nil)))),
  787.       NewSubMenu('~W~indow', hcNoContext,
  788.       NewMenu(
  789.         NewItem('~N~ext',                   'F6',   kbF6,     cmNext,           hcNoContext,
  790.         NewItem('~Z~oom',                   'F5',   kbF5,     cmZoom,           hcNoContext,
  791.         NewItem('~T~ile',                   '',     kbNoKey,  cmTile,           hcNoContext,
  792.         NewItem('~C~ascade',                '',     kbNoKey,  cmCascade,        hcNoContext,
  793.         nil))))),
  794.       NewSubMenu('~T~est', hcNoContext,
  795.       NewMenu(
  796.         NewItem('~D~ata Entry...',          '',     kbNoKey,  cmNewEditLine,    hcNoContext,
  797.         NewItem('Picture ~V~alidators...',  '',     kbNoKey,  cmTestPictures,   hcNoContext,
  798.         NewItem('~M~essage Dialog...',      '',     kbNoKey,  cmMsgDialog,      hcNoContext,
  799.         NewItem('Standard File ~V~iewer',   '',     kbNoKey,  cmNewWin,         hcNoContext,
  800.         NewItem('~T~ext Display Window',    '',     kbNoKey,  cmNewText,        hcNoContext,
  801.         NewItem('~F~ormatted File Viewer',  '',     kbNoKey,  cmNewFormatText,  hcNoContext,
  802.         NewItem('~A~scii/Hex Editor',       '',     kbNoKey,  cmNewAsciiHex,    hcNoContext,
  803.         NewItem('~P~rogress Dialog',        '',     kbNoKey,  cmTestPct,        hcNoContext,
  804.         NewItem('P~r~int Dialog',           '',     kbNoKey,  cmTestPrt,        hcNoContext,
  805.         NewItem('~3~D Controls',            '',     kbNoKey,  cmTest3D,         hcNoContext,
  806.         NewItem('~W~riteln to Window',      '',     kbNoKey,  cmTestWrite,      hcNoContext,
  807.         NewItem('Multi-Select ~L~ist Box',  '',     kbNoKey,  cmTestBox1,      hcNoContext,
  808.         NewItem('Paired List ~B~oxes',      '',     kbNoKey,  cmTestBox2,      hcNoContext,
  809.         NewItem('Virtual List Boxes',       '',     kbNoKey,  cmTestBox3,      hcNoContext,
  810.         NewSubMenu('~C~heck Marks', hcNoContext,
  811.         NewMenu(
  812.           NewMarkedItem(S + 'Item 1',       '',     kbNoKey,  cmItem1,          hcNoContext,
  813.           NewMarkedItem(S + 'Item 2',       '',     kbNoKey,  cmItem2,          hcNoContext,
  814.           NewMarkedItem(S + 'Item 3',       '',     kbNoKey,  cmItem3,          hcNoContext,
  815.           NewMarkedItem(S + 'Item 4',       '',     kbNoKey,  cmItem4,          hcNoContext,
  816.           nil))))),
  817.         nil)))))))))))))))),
  818.       NewSubMenu('~O~ptions', hcNoContext,
  819.       NewMenu(
  820.         NewItem('~S~etup',                  '',     kbNoKey,  cmSetup,          hcNoContext,
  821.         nil)),
  822.       nil)))))
  823.     )));
  824.  
  825.     PbxMenuBar(MenuBar)^.SetMarker(cmItem1);
  826.   end;
  827.  
  828. Procedure TMyApp.InitStatusLine;
  829.  
  830.   var
  831.     R : TRect;
  832.  
  833.   begin
  834.     GetExtent(R);
  835.     R.A.Y := R.B.Y - 1;
  836.     StatusLine := New(PStatusLine, Init(R,
  837.       NewStatusDef(0, $FFFF,
  838.         NewStatusKey('', kbF10, cmMenu,
  839.         NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
  840.         NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose,
  841.         nil))),
  842.       nil)
  843.     ));
  844.   end;
  845.  
  846. Procedure TMyApp.ReadFile(FileToRead : PathStr);
  847.  
  848.   var
  849.     F : Text;
  850.     N : string[5];
  851.     S : String;
  852.     Err : Integer;
  853.  
  854.   begin
  855.     ShowBusy;
  856.     BufSize := 0;
  857.     LineCount := 0;
  858.     Assign(F, FileToRead);
  859.     {$I-}
  860.     Reset(F);
  861.     Err := IOResult;
  862.     {$I+}
  863.  
  864.     if (Err <> 0) then
  865.     begin
  866.       HideBusy;
  867.       Str(Err, N);
  868.       S := 'COULD NOT READ FILE ' + ^M +
  869.            FileToRead + ^M +
  870.            ' I/O ERROR #' + N;
  871.       MessageBox(S, nil, mfError or mfOkButton);
  872.       EXIT;
  873.     end;
  874.  
  875.     BufName := FileToRead;
  876.     GetMem(Buf, MaxBuf);
  877.     FillChar(Buf^, MaxBuf, 0);
  878.  
  879.     while not Eof(F) and (LineCount < MaxLines) do
  880.     begin
  881.       Readln(F, S);
  882.       Lines[LineCount] := NewStr(S);
  883.       Inc(LineCount);
  884.  
  885.       if (BufSize + Length(S) < MaxBuf - 2) then
  886.       begin
  887.         if (S = '') then
  888.         begin
  889.           Buf^[BufSize-1]:= #13;
  890.           Buf^[BufSize]  := #13;
  891.           Inc(BufSize);
  892.         end
  893.  
  894.         else
  895.         begin
  896.           Move(S[1], Buf^[BufSize], Byte(S[0]));
  897.           Inc(BufSize, Length(S));
  898.           Buf^[BufSize]  := #32;
  899.           Inc(BufSize);
  900.         end;
  901.       end;
  902.     end;
  903.  
  904.     Close(F);
  905.     HideBusy;
  906.   end;
  907.  
  908. Procedure TMyApp.OpenFile;
  909.  
  910.   var
  911.     FileName  : PathStr;
  912.     {$IFDEF USE_NEW_FILE_DIALOG}
  913.     Dialog    : PbxFileDialog;
  914.     {$ELSE}
  915.     Dialog    : PFileDialog;
  916.     {$ENDIF}
  917.  
  918.   begin
  919.     {$IFDEF USE_NEW_FILE_DIALOG}
  920.     Dialog := New(PbxFileDialog, Init('*.*', 'Open a File',
  921.                                       'File~n~ame',
  922.                                       fdOpenButton + fdHelpButton, 100));
  923.     {$ELSE}
  924.     Dialog := New(PFileDialog, Init('*.*', 'Open a File',
  925.                                     'File~n~ame',
  926.                                     fdOpenButton + fdHelpButton, 100));
  927.     {$ENDIF}
  928.  
  929.     if ExecView(Dialog) <> cmCancel then
  930.     begin
  931.       Dialog^.GetFileName(FileName);
  932.       EnableCommands([cmNewWin..cmNewAsciiHex]);
  933.       DisableCommands([cmFileOpen]);
  934.       ReadFile(FileName);
  935.     end;
  936.  
  937.     Dispose(Dialog, Done);
  938.   end;
  939.  
  940. procedure TMyApp.NewWindow;
  941.   var
  942.     Window : PFileWindow;
  943.     R : TRect;
  944.  
  945.   begin
  946.     Inc(WinCount);
  947.     R.Assign(0, 0, 45, 13);
  948.     R.Move(Random(34), Random(11));
  949.     Window := New(PFileWindow, Init(R, 'Standard Viewer: ' + BufName, wnNoNumber));
  950.     DeskTop^.Insert(Window);
  951.   end;
  952.  
  953. Procedure TMyApp.MessageDialog;
  954.  
  955.   var
  956.     Dialog : PbxMessageDialog;
  957.  
  958.   begin
  959.     { All these messages will be displayed when the dialog is executed.
  960.       The dialog will size it self to fit the buttons and all text.
  961.     }
  962.     New(Dialog, Init(mfInformation + mfOKButton));
  963.     Dialog^.AddMessage('');
  964.     Dialog^.AddMessage(' -------------- TMessageDialog -------------- ');
  965.     Dialog^.AddMessage(' It is simple to add text, just make a call');
  966.     Dialog^.AddMessage(' to the TMessageDialog.AddMessage method! The');
  967.     Dialog^.AddMessage(' message box will size itself to the amount');
  968.     Dialog^.AddMessage(' of text that is added.');
  969.     Dialog^.AddMessage(' -------------------------------------------- ');
  970.     ExecuteDialog(Dialog, nil);
  971.   end;
  972.  
  973. Procedure TMyApp.Setup;
  974.  
  975.   var
  976.     Dialog  : PDialog;
  977.     R       : TRect;
  978.     Control : PView;
  979.     Command : Word;
  980.     MState  : Word;
  981.  
  982.   begin
  983.     { make a dialog box to get the mouse toggle option }
  984.     R.Assign(0,0,53,12);
  985.     New(Dialog, Init(R, 'Setup'));
  986.  
  987.     with Dialog^ do
  988.     begin
  989.       Options := Options OR ofCentered;
  990.       R.Assign(2,2,51,3);
  991.       Control := New(PCheckboxes, Init(R,
  992.                    NewSItem('Turn mouse cursor off when keyboard is used',Nil)));
  993.       PCluster(Control)^.Value := 0;
  994.       Insert(Control);
  995.  
  996.       R.Assign(10,8,18,10);
  997.       Insert(New(PButton, Init(R, '~O~K', cmOK, bfDefault)));
  998.  
  999.       R.Assign(29,8,41,10);
  1000.       Insert(New(PButton, Init(R, '~C~ancel', cmCancel, bfNormal)));
  1001.  
  1002.       SelectNext(False);
  1003.  
  1004.       { get current state }
  1005.       if ToggleMouse then
  1006.         MState := 1
  1007.       else
  1008.         MState := 0;
  1009.  
  1010.       { execute the dialog and set mouse toggle flag as specified }
  1011.       if (ExecuteDialog(Dialog, @MState) <> cmCancel) then
  1012.       begin
  1013.         if (MState = 1) then
  1014.           SetMouseToggle(True)
  1015.         else
  1016.           SetMouseToggle(False);
  1017.       end;
  1018.     end;
  1019.   end;
  1020.  
  1021. Procedure TMyApp.PercentTest;
  1022.  
  1023.   var
  1024.     Dialog : PPctDialog;
  1025.  
  1026.   begin
  1027.     New(Dialog, Init('', 'Your Message Here', 1000,
  1028.                      mfOKPauseCancel OR mfMessageLine));
  1029.     ExecuteDialog(Dialog, nil);
  1030.   end;
  1031.  
  1032. Procedure TMyApp.PrintTest;
  1033.  
  1034.   var
  1035.     Dialog : PPrtDialog;
  1036.  
  1037.   begin
  1038.     New(Dialog, Init('PRINT', '', mfOKPauseCancel OR mfMessageLine));
  1039.     ExecuteDialog(Dialog, nil);
  1040.   end;
  1041.  
  1042. Procedure TMyApp.Test3D;
  1043.  
  1044.   var
  1045.     Dialog  : Pbx3DDialog;
  1046.     R       : TRect;
  1047.     P       : PView;
  1048.     Bar     : PScrollBar;
  1049.     List    : PCityColl;
  1050.  
  1051.   begin
  1052.     { create a 3D dialog box with all possible 3D controls }
  1053.     R.Assign(0,0,60,20);
  1054.     New(Dialog, Init(R, '3D Controls'));
  1055.  
  1056.     with Dialog^ do
  1057.     begin
  1058.       Options := Options or ofCentered;
  1059.  
  1060.       { 3D input lines }
  1061.       R.Assign(3,3, 14,4);
  1062.       P := New(PInputLine, Init(R, 15));
  1063.       P^.Options := P^.Options or ofFramed;
  1064.       Insert(P);
  1065.  
  1066.       R.Assign(3,2, 11,3);
  1067.       Insert(New(PLabel, Init(R, '~T~ext 2', P)));
  1068.  
  1069.       R.Assign(15,3, 18,4);
  1070.       Insert(New(Pbx3DHistory, Init(R, PInputLine(P), 10)));
  1071.  
  1072.       R.Assign(3,6, 14,7);
  1073.       P := New(PInputLine, Init(R, 15));
  1074.       P^.Options := P^.Options or ofFramed;
  1075.       Insert(P);
  1076.  
  1077.       R.Assign(3,5, 11,6);
  1078.       Insert(New(PLabel, Init(R, '~T~ext 1', P)));
  1079.  
  1080.       { 3D Check Boxes }
  1081.       R.Assign(3,9, 15,12);
  1082.  
  1083.       P := New(PCheckBoxes, Init(R,
  1084.         NewSItem('~R~ed',
  1085.         NewSItem('~G~reen',
  1086.         NewSItem('~B~lue', nil)))));
  1087.       P^.Options := P^.Options or ofFramed;
  1088.       Insert(P);
  1089.       PCheckBoxes(P)^.SetButtonState(1, False);
  1090.  
  1091.       R.Assign(3,8, 14,9);
  1092.       Insert(New(PLabel, Init(R, '~C~heck Box', P)));
  1093.  
  1094.       { 3D Radio Buttons }
  1095.       R.Assign(3,14, 15,18);
  1096.  
  1097.       P := New(PRadioButtons, Init(R,
  1098.         NewSItem('~N~orth',
  1099.         NewSItem('~E~ast',
  1100.         NewSItem('~S~outh',
  1101.         NewSItem('~W~est', nil))))));
  1102.       P^.Options := P^.Options or ofFramed;
  1103.       Insert(P);
  1104.  
  1105.       R.Assign(3,13, 14,14);
  1106.       Insert(New(PLabel, Init(R, '~R~adio Btn', P)));
  1107.  
  1108.       { 3D List Box }
  1109.       R.Assign(40,3, 41,10);
  1110.       New(Bar, Init(R));
  1111.       Insert(Bar);
  1112.  
  1113.       R.Assign(22,3, 39,10);
  1114.       P := New(PbxLinkedBox, Init(R, 1, Bar, 5001));
  1115.       P^.Options := P^.Options or ofFramed;
  1116.       Insert(P);
  1117.       List := New(PCityColl, Init);
  1118.       PListBox(P)^.NewList(List);
  1119.  
  1120.       R.Assign(22,2, 32,3);
  1121.       Insert(New(PLabel, Init(R, 'List Box', P)));
  1122.  
  1123.       R.Assign(22,12, 39,13);
  1124.       P := New(PbxLinkedLine, Init(R, 15, 5001));
  1125.       P^.Options := P^.Options or ofFramed;
  1126.       Insert(P);
  1127.  
  1128.       { Static Text }
  1129.  
  1130.       R.Assign(22,15, 39,16);
  1131.       P := New(PStaticText, Init(R, 'Static Text'));
  1132.       P^.Options := P^.Options or ofFramed;
  1133.       Insert(P);
  1134.  
  1135.       { 3D Buttons }
  1136.       R.Assign(46,2,58,5);
  1137.       Insert(New(Pbx3DButton, Init(R, 'OK', cmOK, bfDefault)));
  1138.  
  1139.       R.Assign(46,5,58,8);
  1140.       Insert(New(Pbx3DButton, Init(R, '~C~ancel', cmCancel, bfNormal)));
  1141.  
  1142.       R.Assign(46,8,58,12);
  1143.       Insert(New(Pbx3DButton, Init(R, '~O~pen'^M+'File', 5000, bfNormal)));
  1144.  
  1145.       R.Assign(46,12,58,16);
  1146.       Insert(New(Pbx3DButton, Init(R, '~S~ave'^M+'File', 5000, bfNormal)));
  1147.  
  1148.       { 3D Buttons }
  1149.       R.Assign(46,16,58,19);
  1150.       Insert(New(Pbx3DButton, Init(R, '~N~ew', cmNone, bfNormal)));
  1151.       Application^.DisableCommands([cmNone]);
  1152.  
  1153.       SelectNext(False);
  1154.     end;
  1155.  
  1156.     ExecuteDialog(Dialog, nil);
  1157.     Dispose(List, Done);
  1158.   end;
  1159.  
  1160. Procedure TMyApp.About;
  1161.  
  1162.   var
  1163.     Dialog : PbxMessageDialog;
  1164.  
  1165.   begin
  1166.     New(Dialog, Init(mfInformation + mfOKButton));
  1167.  
  1168.     with Dialog^ do
  1169.     begin
  1170.       AddMessage('');
  1171.       AddMessage('               ╔═════╗    ');
  1172.       AddMessage('           ┌───╨─────╨───┐');
  1173.       AddMessage('           ├─────────────┤');
  1174.       AddMessage('           │ TV TOOL BOX │');
  1175.       AddMessage('           └─────────────┘');
  1176.       AddMessage(^C + 'Version 2.0');
  1177.       AddMessage('');
  1178.       AddMessage('  Tools for Turbo Vision Programmers  ');
  1179.       AddMessage('');
  1180.       AddMessage(^C + 'Copyright 1992,1993 Richard Hansen');
  1181.       AddMessage(^C + 'All rights reserved.');
  1182.       AddMessage('');
  1183.     end;
  1184.  
  1185.     ExecuteDialog(Dialog, nil);
  1186.   end;
  1187.  
  1188. Procedure TMyApp.TestSelectBox1;
  1189.  
  1190.   var
  1191.     Dialog  : PDialog;
  1192.     ListBox : PbxCheckListBox;
  1193.     List    : PbxCollection;
  1194.     Bar     : PScrollBar;
  1195.     R       : TRect;
  1196.  
  1197.   begin
  1198.     { MULTI-SELECT LIST BOX }
  1199.     { Multi-select list boxes put [X] in front of each selected entry }
  1200.     R.Assign(13,5,50,18);
  1201.     Dialog := New(PDialog, Init(R, 'Multi-Select List Box'));
  1202.  
  1203.     R.Assign(34,1,35,9);
  1204.     Bar := New(PScrollBar, Init(R));
  1205.     Dialog^.Insert(Bar);
  1206.  
  1207.     List := New(PbxCollection, Init(15, 5));
  1208.     List^.Insert(New(PbxSelectStr, Init('Scotts Valley')));
  1209.     List^.Insert(New(PbxSelectStr, Init('Sydney')));
  1210.     List^.Insert(New(PbxSelectStr, Init('Copenhagen')));
  1211.     List^.Insert(New(PbxSelectStr, Init('London')));
  1212.     List^.Insert(New(PbxSelectStr, Init('Paris')));
  1213.     List^.Insert(New(PbxSelectStr, Init('Munich')));
  1214.     List^.Insert(New(PbxSelectStr, Init('Milan')));
  1215.     List^.Insert(New(PbxSelectStr, Init('Tokyo')));
  1216.     List^.Insert(New(PbxSelectStr, Init('Stockholm')));
  1217.     List^.Insert(New(PbxSelectStr, Init('New York')));
  1218.     List^.Insert(New(PbxSelectStr, Init('Redmond')));
  1219.     List^.Insert(New(PbxSelectStr, Init('Zurich')));
  1220.     List^.Insert(New(PbxSelectStr, Init('Athens')));
  1221.     List^.Insert(New(PbxSelectStr, Init('Brussels')));
  1222.     List^.Insert(New(PbxSelectStr, Init('Chicago')));
  1223.  
  1224.     R.Assign(2,1,34,9);
  1225.     ListBox := New(PbxCheckListBox, Init(R, 1, Bar));
  1226.     ListBox^.NewList(List);
  1227.     { select a couple of items, collections are numbered from zero }
  1228.     ListBox^.SetSelectSet([0,4]);
  1229.     Dialog^.Insert(ListBox);
  1230.  
  1231.     R.Assign(13,10,23,12);
  1232.     Dialog^.Insert(New(PButton, Init(R, 'OK', cmOK, bfDefault)));
  1233.  
  1234.     ExecuteDialog(Dialog, nil);
  1235.     Dispose(List, Done);
  1236.   end;
  1237.  
  1238. Procedure TMyApp.TestSelectBox2;
  1239.  
  1240.   var
  1241.     Dialog  : PDialog;
  1242.     ListBox : PbxPairedListBox;
  1243.     List1   : PbxCollection;
  1244.     List2   : PbxCollection;
  1245.     Bar     : PScrollBar;
  1246.     R       : TRect;
  1247.     i       : Word;
  1248.     S       : String;
  1249.  
  1250.   begin
  1251.     { PAIRED LIST BOXES }
  1252.     { paired list boxes move items from one box to the other }
  1253.     R.Assign(19,5,61,18);
  1254.     Dialog := New(PDialog, Init(R, 'Paired List Boxes'));
  1255.  
  1256.     R.Assign(19,1,20,9);
  1257.     Bar := New(PScrollBar, Init(R));
  1258.     Dialog^.Insert(Bar);
  1259.     R.Assign (2,1,19,9);
  1260.     ListBox := New(PbxPairedListBox, Init(R, 1, Bar));
  1261.     Dialog^.Insert(ListBox);
  1262.     List1 := New(PbxCollection, Init(15, 5));
  1263.     List1^.Insert(New(PbxSelectStr, Init('Scotts Valley')));
  1264.     List1^.Insert(New(PbxSelectStr, Init('Sydney')));
  1265.     List1^.Insert(New(PbxSelectStr, Init('Copenhagen')));
  1266.     List1^.Insert(New(PbxSelectStr, Init('London')));
  1267.     List1^.Insert(New(PbxSelectStr, Init('Paris')));
  1268.     List1^.Insert(New(PbxSelectStr, Init('Munich')));
  1269.     List1^.Insert(New(PbxSelectStr, Init('Milan')));
  1270.     List1^.Insert(New(PbxSelectStr, Init('Tokyo')));
  1271.     List1^.Insert(New(PbxSelectStr, Init('Stockholm')));
  1272.     List1^.Insert(New(PbxSelectStr, Init('New York')));
  1273.     List1^.Insert(New(PbxSelectStr, Init('Redmond')));
  1274.     List1^.Insert(New(PbxSelectStr, Init('Zurich')));
  1275.     List1^.Insert(New(PbxSelectStr, Init('Athens')));
  1276.     List1^.Insert(New(PbxSelectStr, Init('Brussels')));
  1277.     List1^.Insert(New(PbxSelectStr, Init('Chicago')));
  1278.     ListBox^.NewList(List1);
  1279.  
  1280.     R.Assign(39,1,40,9);
  1281.     Bar := New(PScrollBar, Init(R));
  1282.     Dialog^.Insert(Bar);
  1283.     R.Assign(22,1,39,9);
  1284.     ListBox := New(PbxPairedListBox, Init(R, 1, Bar));
  1285.     Dialog^.Insert(ListBox);
  1286.     List2 := New(PbxCollection, Init(15,5));
  1287.     ListBox^.NewList(List2);
  1288.  
  1289.     R.Assign(16,10,26,12);
  1290.     Dialog^.Insert(New(PButton, Init(R, 'OK', cmOK, bfDefault)));
  1291.  
  1292.     Dialog^.SelectNext (False);
  1293.  
  1294.     if ExecuteDialog(Dialog, nil) <> cmCancel then
  1295.     begin
  1296.       { Send the selected items to any TbxTextWindows open on the desktop }
  1297.       S := '';
  1298.       Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1299.       S := '<<< HERE IS WHAT YOU JUST SELECTED >>>';
  1300.       Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1301.  
  1302.       for i := 1 to List2^.Count do
  1303.       begin
  1304.         S := PbxObject(List2^.At(i - 1))^.GetText(255);
  1305.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1306.       end;
  1307.     end
  1308.  
  1309.     else
  1310.     begin
  1311.       S := '';
  1312.       Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1313.       S := '<<< YOU PRESSED ESCAPE? >>>';
  1314.       Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1315.     end;
  1316.  
  1317.     Dispose(List1, Done);
  1318.     Dispose(List2, Done);
  1319.   end;
  1320.  
  1321. Procedure TMyApp.WritelnText;
  1322.  
  1323.   var
  1324.     W : PbxTextWindow;
  1325.     R : TRect;
  1326.  
  1327.   begin
  1328.     { WRITELN TO A TEXT WINDOW }
  1329.     R.Assign(0, 0, 40, 13);
  1330.     W := New(PbxTextWindow, Init(R, 'Standard Output', wnNoNumber,
  1331.                                  ofVScrollBar or ofHScrollBar, 25));
  1332.     W^.Options := W^.Options or OfCentered;
  1333.     DeskTop^.Insert(W);
  1334.  
  1335.     { redirect standard writes }
  1336.     AssignOutput(Output, W);
  1337.     Rewrite(Output);
  1338.     Writeln('THIS TEXT IS DISPLAYED THROUGH THE STANDARD WRITE AND');
  1339.     Writeln('WRITELN STATEMENTS.');
  1340.     Writeln('THE STANDARD OUTPUT HAS BEEN REDIRECTED TO THIS WINDOW.');
  1341.     Writeln('OPEN THE PAIRED LIST BOX, SELECT ONE OR TWO ITEMS AND');
  1342.     Writeln('THEN PRESS THE "OK" BUTTON.');
  1343.     Writeln('');
  1344.     Writeln('IF YOU OPEN THE DATA ENTRY TEST DIALOG, YOUR ENTRIES');
  1345.     Writeln('WILL BE ECHOED HERE.');
  1346.     { restore standard output }
  1347.     Close(Output);
  1348.     Assign(Output, '');
  1349.     Rewrite(Output);
  1350.   end;
  1351.  
  1352. Procedure TMyApp.NewText;
  1353.  
  1354.   var
  1355.     R     : TRect;
  1356.     W     : PbxTextWindow;
  1357.  
  1358.   begin
  1359.     { A TEXT WINDOW FOR EASY OUTPUT }
  1360.     Inc(WinCount);
  1361.     R.Assign(0, 0, 60, 13);
  1362.     R.Move(Random(19), Random(10));
  1363.     W := New(PbxTextWindow, Init(R, 'Text Window', WinCount,
  1364.                                  ofVScrollBar or ofHScrollBar, 25));
  1365.     W^.Options := W^.Options OR ofTileable;
  1366.     DeskTop^.Insert(W);
  1367.  
  1368.     W^.Write('');
  1369.     W^.Write(' ┌───────────────────────────────────────────────────────┐ ');
  1370.     W^.Write(' │ THIS MAY NOT LOOK LIKE MUCH HERE, BUT CHECK OUT THE   │ ');
  1371.     W^.Write(' │ EXAMPLE CODE AND YOU WILL SEE THAT THIS IS A TEXT     │ ');
  1372.     W^.Write(' │ DISPLAY WINDOW WITHOUT A CUSTOMIZED DRAW METHOD. JUST │ ');
  1373.     W^.Write(' │ THE THING FOR A LITTLE QUICK AND EASY TEXT DISPLAY!   │ ');
  1374.     W^.Write(' │ OPEN THE DATA ENTRY DIALOG, ENTER SOME DATA, AND HIT  │ ');
  1375.     W^.Write(' │ "OK" WHEN THIS WINDOW IS OPEN.                        │ ');
  1376.     W^.Write(' └───────────────────────────────────────────────────────┘ ');
  1377.     W^.Write('');
  1378.   end;
  1379.  
  1380. Procedure TMyApp.NewFormatText;
  1381.  
  1382.   var
  1383.     W   : PbxWindow;
  1384.     R   : TRect;
  1385.     Bar : PScrollBar;
  1386.  
  1387.   begin
  1388.     { FORMATTED TEXT WINDOW }
  1389.     Inc(WinCount);
  1390.     R.Assign(0, 0, Desktop^.Size.X, Desktop^.Size.Y);
  1391.     W := New(PbxWindow, Init(R, 'Formatted Text Scroller: ' + BufName, WinCount));
  1392.     W^.Options := W^.Options OR ofTileable OR ofCentered;
  1393.  
  1394.     W^.GetExtent(R);
  1395.     R.Assign(R.B.X-1, R.A.Y+1, R.B.X, R.B.Y-1);
  1396.     Bar := New(PScrollBar, Init(R));
  1397.     Bar^.Options := Bar^.Options or ofPostProcess;
  1398.     W^.Insert(Bar);
  1399.  
  1400.     W^.GetExtent(R);
  1401.     R.Grow(-1, -1);
  1402.     W^.Insert(New(PbxFormattedTextScroller, Init(R, Bar, Buf, BufSize)));
  1403.  
  1404.     DeskTop^.Insert(W);
  1405.   end;
  1406.  
  1407.  
  1408. Procedure TMyApp.NewAsciiHex;
  1409.  
  1410.   var
  1411.     Window: PbxAsciiHexEditor;
  1412.     R     : TRect;
  1413.  
  1414.   begin
  1415.     { ASCII/HEX EDIT BUFFER }
  1416.     Inc(WinCount);
  1417.     R.Assign(1,1, 64,16);
  1418.     Window := New(PbxAsciiHexEditor, Init(R, 'Ascii/Hex Editor: ' + BufName,
  1419.                                           WinCount, ofPosIndicator,
  1420.                                           Buf, MaxBuf));
  1421.     Window^.Options := Window^.Options OR ofTileable;
  1422.     DeskTop^.Insert(Window);
  1423.   end;
  1424.  
  1425. Procedure TMyApp.NewDataEntry;
  1426.  
  1427.   var
  1428.     Dialog  : PbxEntryDialog;
  1429.     R       : TRect;
  1430.     E       : PbxEditLine;
  1431.     L       :  PLabel;
  1432.     S       : String;
  1433.     SpinBar : PbxSpinBar;
  1434.     Slider  : PbxSlider;
  1435.  
  1436.   begin
  1437.     { DATA ENTRY WITH EDIT MASKS }
  1438.     TvInput.SetDateDefaults;
  1439.     R.Assign(0,0, 75,17);
  1440.     Dialog := New(PbxEntryDialog, Init(R, 'Data Entry Test'));
  1441.  
  1442.     With Dialog^ do
  1443.     begin
  1444.       Options := Options or ofCentered;
  1445.  
  1446.       { date entry using string field }
  1447.       {S1}
  1448.       R.Assign(2,2, 14,3);
  1449.       E := New(PbxEditLine, Init(R, '99/99/9999'));
  1450.       Insert(E);
  1451.       R.Assign(2,1, 19,2);
  1452.       L := New(PLabel, Init(R, '~D~ate String', E));
  1453.       Insert(L);
  1454.       E^.AddLabel(L);
  1455.  
  1456.       { scrolling phone numbers }
  1457.       {S2}
  1458.       R.Assign(2,4, 19,5);
  1459.       E := New(PbxEditLine, Init(R, '(999) 999-9999 [9999]'));
  1460.       Insert(E);
  1461.       R.Assign(2,3, 19,4);
  1462.       L := New(PLabel, Init(R, 'Phone Number 1', E));
  1463.       Insert(L);
  1464.       E^.AddLabel(L);
  1465.  
  1466.       {S3}
  1467.       R.Assign(2,6, 26,7);
  1468.       E := New(PbxEditLine, Init(R, '(999) 999-9999 [9999]'));
  1469.       Insert(E);
  1470.       R.Assign(2,5, 19,6);
  1471.       L := New(PLabel, Init(R, 'Phone Number 2', E));
  1472.       Insert(L);
  1473.       E^.AddLabel(L);
  1474.  
  1475.       { locked phone number }
  1476.       {S4}
  1477.       R.Assign(2,8, 19,9);
  1478.       E := New(PbxEditLine, Init(R, '(999) 999-9999 [9999]'));
  1479.       Insert(E);
  1480.       R.Assign(2,7, 19,8);
  1481.       L := New(PLabel, Init(R, '~L~ocked Field', E));
  1482.       Insert(L);
  1483.       E^.AddLabel(L);
  1484.       E^.Lock;
  1485.  
  1486.       { unsigned integer, no range checking}
  1487.       {I1}
  1488.       R.Assign(2,10, 10,11);
  1489.       E := New(PbxWordEdit, Init(R, '99999', 0, 0));
  1490.       Insert(E);
  1491.       E^.SetEditFlag(dfLJustify, True);
  1492.       R.Assign(2,9, 19,10);
  1493.       L := New(PLabel, Init(R, 'U~n~signed Integer', E));
  1494.       Insert(L);
  1495.       E^.AddLabel(L);
  1496.  
  1497.       { signed integer, range -1000 to 1000 }
  1498.       {I2}
  1499.       R.Assign(2,12, 11,13);
  1500.       E := New(PbxIntegerEdit, Init(R, '#####', -1000, 1000));
  1501.       Insert(E);
  1502.       E^.SetEditFlag(dfRJustify, True);
  1503.       R.Assign(2,11,  19,12);
  1504.       L := New(PLabel, Init(R, '~S~igned Integer', E));
  1505.       Insert(L);
  1506.       E^.AddLabel(L);
  1507.  
  1508.       { hex integer }
  1509.       {H1}
  1510.       R.Assign(30,2, 37,3);
  1511.       E := New(PbxHexEdit, Init(R, '&&&&&', 0, 0));
  1512.       Insert(E);
  1513.       R.Assign(30,1,  47,2);
  1514.       Insert(New(PLabel, Init(R, '~H~exadecimal', E)));
  1515.  
  1516.       { password fields }
  1517.       {S5}
  1518.       R.Assign(30,4, 40,5);
  1519.       E := New(PbxEditLine, Init(R, 'XXXXXXXX'));
  1520.       E^.SetEditFlag(dfHide, True);
  1521.       Insert(E);
  1522.       R.Assign(30,3, 47,4);
  1523.       Insert(New(PLabel, Init(R, '~P~assword Fields', E)));
  1524.  
  1525.       { alternate padding chars }
  1526.       {S6}
  1527.       R.Assign(30,6, 40,7);
  1528.       E := New(PbxEditLine, Init(R, 'XXXXXXXX'));
  1529.       E^.PadChar := '_';
  1530.       E^.SetEditFlag(dfTrim, True);
  1531.       Insert(E);
  1532.  
  1533.       { upper case only }
  1534.       {S7}
  1535.       R.Assign(30,8, 42,9);
  1536.       E := New(PbxEditLine, Init(R, 'UUUUUUUUUU'));
  1537.       Insert(E);
  1538.       E^.SetEditFlag(dfRequired, True);
  1539.       R.Assign(30,7, 53,8);
  1540.       Insert(New(PLabel, Init(R, 'Any Char Force ~U~pper', E)));
  1541.  
  1542.       { alphanumeric upper case only }
  1543.       {S8}
  1544.       R.Assign(30,10, 42,11);
  1545.       E := New(PbxEditLine, Init(R, 'llllllllll'));
  1546.       Insert(E);
  1547.       E^.SetEditFlag(dfLJustify or dfTrim, True);
  1548.       R.Assign(30,9, 53,10);
  1549.       Insert(New(PLabel, Init(R, '~A~lphanumeric Force Lower', E)));
  1550.  
  1551.       { floating point (REAL) }
  1552.       {R1}
  1553.       R.Assign(30,12, 41,13);
  1554.       E := New(PbxRealEdit, Init(R, '####.###', 0.0, 0.0));
  1555.       Insert(E);
  1556.       R.Assign(30,11, 53,12);
  1557.       Insert(New(PLabel, Init(R, '~F~loating point', E)));
  1558.  
  1559.       { floating point (DOUBLE) as Money }
  1560.       {D1}
  1561.       {$IFOPT N+}
  1562.       R.Assign(55,2, 67,3);
  1563.       E := New(PbxDoubleEdit, Init(R, '$#####.##', 0.0, 50000.0));
  1564.       Insert(E);
  1565.       R.Assign(55,1, 68,2);
  1566.       Insert(New(PLabel, Init(R, '~M~oney', E)));
  1567.       {$ENDIF}
  1568.  
  1569.       R.Assign(55,4, 69,5);
  1570.       E := New(PbxEditLine, Init(R, 'XXXXXXXXXXXX'));
  1571.       Insert(E);
  1572.       E^.Options := E^.Options or ofValidate;
  1573.       E^.SetValidator(New(PMyValidator, Init));
  1574.       R.Assign(55,3, 70,4);
  1575.       Insert(New(PLabel, Init(R, 'With ~V~alidator', E)));
  1576.  
  1577.       { date entry using date field }
  1578.       R.Assign(55,6, 65,7);
  1579.       E := New(PbxDateEdit, Init(R, 'mm/dd/yy'));
  1580.       Insert(E);
  1581.       E^.SetEditFlag(dfDefaults, True);
  1582.       R.Assign(55,5, 63,6);
  1583.       L := New(PLabel, Init(R, 'Date 1', E));
  1584.       Insert(L);
  1585.       E^.AddLabel(L);
  1586.  
  1587.       R.Assign(55,8, 67,9);
  1588.       E := New(PbxDateEdit, Init(R, 'DD/MM/YYYY'));
  1589.       Insert(E);
  1590.       E^.Options := E^.Options or ofValidate;
  1591.       R.Assign(55,7, 63,8);
  1592.       L := New(PLabel, Init(R, 'Date 2', E));
  1593.       Insert(L);
  1594.       E^.AddLabel(L);
  1595.  
  1596.       { SX1 }
  1597.       { a slider }
  1598.       R.Assign(55,10, 67,12);
  1599.       Slider := New(PbxSlider, Init(R, 1, 50, 'Slow', 'Fast'));
  1600.       Insert(Slider);
  1601.  
  1602.       R.Assign(55,9, 70,10);
  1603.       Insert(New(PLabel, Init(R, 'Slider Control', Slider)));
  1604.  
  1605.       { SX2 }
  1606.       { a vertical spinner }
  1607.       R.Assign(61,14, 62,16);
  1608.       SpinBar := New(PbxSpinBar, Init(R));
  1609.       SpinBar^.SetParams(0, -50,50, 1,5);
  1610.       R.Assign(55,14, 60,15);
  1611.       Insert(New(PbxSpinEdit, Init(R, '###', SpinBar)));
  1612.       Insert(SpinBar);
  1613.  
  1614.       { SX3 }
  1615.       { a horizontal spinner }
  1616.       R.Assign(69,14, 71,15);
  1617.       SpinBar := New(PbxSpinBar, Init(R));
  1618.       SpinBar^.SetParams(0, -50,50, 1,1);
  1619.       R.Assign(63,14, 68,15);
  1620.       Insert(New(PbxSpinEdit, Init(R, '###', SpinBar)));
  1621.       Insert(SpinBar);
  1622.  
  1623.       R.Assign(55,13, 68,14);
  1624.       Insert(New(PStaticText, Init(R, 'Spin Controls')));
  1625.  
  1626.       R.Assign(15,14, 23,16);
  1627.       Insert(New(PButton, Init(R, 'O~K~', cmOk, bfDefault)));
  1628.  
  1629.       R.Assign(30,14, 44,16);
  1630.       Insert(New(PButton, Init(R, '~C~ancel', cmCancel, bfNormal)));
  1631.  
  1632.       SelectNext(False);
  1633.     end;
  1634.  
  1635.     if (DlgData.X = 0) then
  1636.     with DlgData do
  1637.     begin
  1638.       Inc(X);
  1639.       S1 := '06/01/1993';
  1640.       S2 := '(999) 999-9999 [9999]';
  1641.       S3 := '(999) 999-9999 [9999]';
  1642.       S4 := '(999) 999-9999 [9999]';
  1643.       I1 := 123;
  1644.       I2 := 456;
  1645.       H1 := $FF;
  1646.       S5 := 'DEMO';
  1647.       S6 := 'TEST';
  1648.       S7 := 'ABCDE';
  1649.       S8 := 'wxyz';
  1650.       R1 := 99.99;
  1651.       {$IFOPT N+}
  1652.       D1 := 12345.67;
  1653.       {$ENDIF}
  1654.       S9 := 'VALIDATE ME';
  1655.       Dt1.Year := 78;
  1656.       Dt1.Month:= 2;
  1657.       Dt1.Day  := 6;
  1658.  
  1659.       Dt2.Year := 1980;
  1660.       Dt2.Month:= 8;
  1661.       Dt2.Day  := 9;
  1662.       SX1 := 25;
  1663.       SX2 := -10;
  1664.       SX3 := 10;
  1665.     end;
  1666.  
  1667.     if (ExecuteDialog(Dialog, @DlgData) <> cmCancel) then
  1668.     begin
  1669.       with DlgData do
  1670.       begin
  1671.         { Dump all the data to any TbxTextWindows open on the desktop }
  1672.         Message(Desktop, evBroadcast, cmDisplayClr, nil);
  1673.         S := '<<< HERE IS WHAT YOU JUST ENTERED IN THE DIALOG BOX >>>';
  1674.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1675.         S := '';
  1676.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1677.         Message(Desktop, evBroadcast, cmDisplayStr, @S1);
  1678.         Message(Desktop, evBroadcast, cmDisplayStr, @S2);
  1679.         Message(Desktop, evBroadcast, cmDisplayStr, @S3);
  1680.         Str(I1, S);
  1681.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1682.         Str(I2, S);
  1683.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1684.         Str(H1, S);
  1685.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1686.         Message(Desktop, evBroadcast, cmDisplayStr, @S5);
  1687.         Message(Desktop, evBroadcast, cmDisplayStr, @S6);
  1688.         Message(Desktop, evBroadcast, cmDisplayStr, @S7);
  1689.         Message(Desktop, evBroadcast, cmDisplayStr, @S8);
  1690.         Str(R1:9:3, S);
  1691.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1692.         {$IFOPT N+}
  1693.         Str(D1:9:3, S);
  1694.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1695.         {$ENDIF}
  1696.         Message(Desktop, evBroadcast, cmDisplayStr, @S9);
  1697.         S := DateToDateString(Dt1, 'mm/dd/yy');
  1698.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1699.         S := DateToDateString(Dt2, 'DD/MM/YYYY');
  1700.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1701.         Str(SX1:3, S);
  1702.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1703.         Str(SX2:3, S);
  1704.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1705.         Str(SX3:3, S);
  1706.         Message(Desktop, evBroadcast, cmDisplayStr, @S);
  1707.       end;
  1708.     end;
  1709.   end;
  1710.  
  1711. Procedure TMyApp.TestPictures;
  1712.   var
  1713.     Dlg : PDialog;
  1714.     R   : TRect;
  1715.     Control : PInputLine;
  1716.  
  1717.   begin
  1718.     { TEST SOME PICTURES VALIDATORS }
  1719.     R.Assign(0,0,80,23);
  1720.     New(Dlg, Init(R, 'Picture Validator Test'));
  1721.     Dlg^.Options := Dlg^.Options or ofCentered;
  1722.  
  1723.     R.Assign(2,2,18,3);
  1724.     Control := New(PInputLine, Init(R, 14));
  1725.     Control^.Options := $1405;
  1726.     Dlg^.Insert(Control);
  1727.     Control^.SetValidator(New(PPXPictureValidator, Init(UnsignedPic2, True)));
  1728.     R.Assign(2,1,20,2);
  1729.     Dlg^.Insert(New(PLabel, Init(R, 'Number 1', Control)));
  1730.     R.Assign(19,2,48,3);
  1731.     Dlg^.Insert(New(PStaticText, Init(R, 'Unsigned Int, Commas Required')));
  1732.  
  1733.     R.Assign(2,4,18,5);
  1734.     Control := New(PInputLine, Init(R, 14));
  1735.     Control^.Options := $1405;
  1736.     Dlg^.Insert(Control);
  1737.     Control^.SetValidator(New(PPXPictureValidator, Init(SignedPic1, True)));
  1738.     R.Assign(2,3,20,4);
  1739.     Dlg^.Insert(New(PLabel, Init(R, 'Number 2', Control)));
  1740.     R.Assign(19,4,46,5);
  1741.     Dlg^.Insert(New(PStaticText, Init(R, 'Signed Int, Commas Optional')));
  1742.  
  1743.     R.Assign(2,6,18,7);
  1744.     Control := New(PInputLine, Init(R, 14));
  1745.     Control^.Options := $1005;
  1746.     Dlg^.Insert(Control);
  1747.     Control^.SetValidator(New(PPXPictureValidator, Init(MoneyPic2, True)));
  1748.     R.Assign(2,5,10,6);
  1749.     Dlg^.Insert(New(PLabel, Init(R, 'Money 1', Control)));
  1750.     R.Assign(19,6,30,7);
  1751.     Dlg^.Insert(New(PStaticText, Init(R, '$ Required')));
  1752.  
  1753.  
  1754.     R.Assign(2,8,18,9);
  1755.     Control := New(PInputLine, Init(R, 14));
  1756.     Control^.Options := $1405;
  1757.     Dlg^.Insert(Control);
  1758.     Control^.SetValidator(New(PPXPictureValidator, Init(MoneyPic1, True)));
  1759.     R.Assign(2,7,10,8);
  1760.     Dlg^.Insert(New(PLabel, Init(R, 'Money 2', Control)));
  1761.     R.Assign(19,8,48,9);
  1762.     Dlg^.Insert(New(PStaticText, Init(R, '$ Optional')));
  1763.  
  1764.     R.Assign(2,10,12,11);
  1765.     Control := New(PInputLine, Init(R, 8));
  1766.     Control^.Options := $1405;
  1767.     Dlg^.Insert(Control);
  1768.     Control^.SetValidator(New(PPXPictureValidator, Init(DatePic1, True)));
  1769.     R.Assign(2,9,9,10);
  1770.     Dlg^.Insert(New(PLabel, Init(R, 'Date 1', Control)));
  1771.     R.Assign(19,10,31,11);
  1772.     Dlg^.Insert(New(PStaticText, Init(R, '2 Digit Year')));
  1773.  
  1774.     R.Assign(2,12,14,13);
  1775.     Control := New(PInputLine, Init(R, 10));
  1776.     Control^.Options := $1405;
  1777.     Dlg^.Insert(Control);
  1778.     Control^.SetValidator(New(PPXPictureValidator, Init(DatePic2, True)));
  1779.     R.Assign(2,11,9,12);
  1780.     Dlg^.Insert(New(PLabel, Init(R, 'Date 2', Control)));
  1781.     R.Assign(19,12,36,13);
  1782.     Dlg^.Insert(New(PStaticText, Init(R, '2 or 4 Digit Year')));
  1783.  
  1784.     R.Assign(2,14,18,15);
  1785.     Control := New(PInputLine, Init(R, 14));
  1786.     Dlg^.Insert(Control);
  1787.     Control^.SetValidator(New(PPXPictureValidator, Init(TimePic1, True)));
  1788.     R.Assign(2,13,7,14);
  1789.     Dlg^.Insert(New(PLabel, Init(R, 'Time', Control)));
  1790.     R.Assign(19,14,45,15);
  1791.     Dlg^.Insert(New(PStaticText, Init(R, 'HH:MM:SS, Seconds Optional')));
  1792.  
  1793.     R.Assign(2,16,18,17);
  1794.     Control := New(PInputLine, Init(R, 14));
  1795.     Dlg^.Insert(Control);
  1796.     Control^.SetValidator(New(PPXPictureValidator, Init(PhonePic1, True)));
  1797.     R.Assign(2,15,10,16);
  1798.     Dlg^.Insert(New(PLabel, Init(R, 'Phone 1', Control)));
  1799.     R.Assign(19,16,37,17);
  1800.     Dlg^.Insert(New(PStaticText, Init(R, 'Area Code Optional')));
  1801.  
  1802.     R.Assign(2,18,18,19);
  1803.     Control := New(PInputLine, Init(R, 14));
  1804.     Dlg^.Insert(Control);
  1805.     Control^.SetValidator(New(PPXPictureValidator, Init(PhonePic2, True)));
  1806.     R.Assign(2,17,10,18);
  1807.     Dlg^.Insert(New(PLabel, Init(R, 'Phone 2', Control)));
  1808.     R.Assign(19,18,37,19);
  1809.     Dlg^.Insert(New(PStaticText, Init(R, 'Area Code Required')));
  1810.  
  1811.     R.Assign(49,2,62,3);
  1812.     Control := New(PInputLine, Init(R, 12));
  1813.     Dlg^.Insert(Control);
  1814.     Control^.SetValidator(New(PPXPictureValidator, Init(SSNPic, True)));
  1815.     R.Assign(49,1,67,2);
  1816.     Dlg^.Insert(New(PLabel, Init(R, 'Social Security #', Control)));
  1817.  
  1818.     R.Assign(49,4,64,5);
  1819.     Control := New(PInputLine, Init(R, 13));
  1820.     Dlg^.Insert(Control);
  1821.     Control^.SetValidator(New(PPXPictureValidator, Init(FilenamePic, True)));
  1822.     R.Assign(49,3,58,4);
  1823.     Dlg^.Insert(New(PLabel, Init(R, 'Filename', Control)));
  1824.  
  1825.     R.Assign(49,6,69,7);
  1826.     Control := New(PInputLine, Init(R, 35));
  1827.     Control^.Options := $1005;
  1828.     Dlg^.Insert(Control);
  1829.     Control^.SetValidator(New(PPXPictureValidator, Init(FirstCharUpPic, True)));
  1830.     R.Assign(49,5,68,6);
  1831.     Dlg^.Insert(New(PLabel, Init(R, 'Uppercase 1st Char', Control)));
  1832.  
  1833.     R.Assign(23,20,31,22);
  1834.     Dlg^.Insert(New(PButton, Init(R, '~O~K', cmCancel, bfDefault)));
  1835.  
  1836.     R.Assign(41,20,51,22);
  1837.     Dlg^.Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal)));
  1838.  
  1839.     Dlg^.SelectNext(False);
  1840.     ExecuteDialog(Dlg, nil);
  1841.   end;
  1842.  
  1843. Procedure TMyApp.TestVList;
  1844.   begin
  1845.     { VIRTUAL LIST BOX }
  1846.     ExecuteDialog(New(PVirtDialog, Init), nil);
  1847.   end;
  1848.  
  1849.  
  1850. VAR
  1851.   MyApp : TMyApp;
  1852.  
  1853. begin
  1854.   MyApp.Init;
  1855.   MyApp.Run;
  1856.   MyApp.Done;
  1857. end.
  1858.  
  1859.